<template>
  <div class="custom-table-container">
    <!-- 搜索区域 -->
    <div v-if="showSearch" class="table-search">
      <el-input
        v-model="searchText"
        placeholder="请输入关键词搜索"
        clearable
        size="small"
        @keyup.enter="handleSearch"
      >
        <template #append>
          <el-button size="small" type="primary" @click="handleSearch">
            <el-icon><Search /></el-icon>
          </el-button>
        </template>
      </el-input>
    </div>

    <!-- 表格工具栏 -->
    <div v-if="toolbar" class="table-toolbar">
      <slot name="toolbar"></slot>
    </div>

    <!-- 表格主体 -->
    <el-table
      v-bind="$attrs"
      v-model:selection="selectedRows"
      :data="tableData"
      :loading="loading"
      border
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
    >
      <!-- 选择列 -->
      <el-table-column
        v-if="showSelection"
        type="selection"
        width="55"
        align="center"
      ></el-table-column>

      <!-- 序号列 -->
      <el-table-column
        v-if="showIndex"
        type="index"
        :label="indexLabel"
        :width="indexWidth"
        align="center"
      ></el-table-column>

      <!-- 动态列 -->
      <template v-for="column in columns" :key="column.prop">
        <el-table-column
          v-bind="column"
          :prop="column.prop"
          :label="column.label"
          :width="column.width"
          :align="column.align || 'left'"
          :sortable="column.sortable || false"
        >
          <template #default="scope">
            <!-- 自定义列内容 -->
            <template v-if="column.slotName">
              <slot :name="column.slotName" :row="scope.row" :index="scope.$index"></slot>
            </template>
            <!-- 格式化显示 -->
            <template v-else-if="column.formatter">
              {{ column.formatter(scope.row, scope.column, scope.row[column.prop], scope.$index) }}
            </template>
            <!-- 默认显示 -->
            <template v-else>
              {{ scope.row[column.prop] }}
            </template>
          </template>

          <!-- 自定义表头 -->
          <template v-if="column.headerSlot" #header>
            <slot :name="column.headerSlot"></slot>
          </template>
        </el-table-column>
      </template>

      <!-- 操作列 -->
      <el-table-column
        v-if="showAction"
        :label="actionLabel"
        :width="actionWidth"
        align="center"
      >
        <template #default="scope">
          <slot name="action" :row="scope.row" :index="scope.$index"></slot>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div v-if="showPagination" class="table-pagination">
      <el-pagination
        :current-page="innerCurrentPage"
        :page-size="innerPageSize"
        :page-sizes="pagination.pageSizes"
        :total="pagination.total"
        :layout="pagination.layout"
        @size-change="handleInnerSizeChange"
        @current-change="handleInnerCurrentChange"
      ></el-pagination>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';
import { Search } from '@element-plus/icons-vue';

const props = defineProps({
  // 表格数据
  data: {
    type: Array,
    default: () => []
  },
  // 列配置
  columns: {
    type: Array,
    required: true
  },
  // 是否显示加载状态
  loading: {
    type: Boolean,
    default: false
  },
  // 是否显示选择框
  showSelection: {
    type: Boolean,
    default: false
  },
  // 是否显示序号
  showIndex: {
    type: Boolean,
    default: false
  },
  // 序号列标题
  indexLabel: {
    type: String,
    default: '序号'
  },
  // 序号列宽度
  indexWidth: {
    type: Number,
    default: 80
  },
  // 是否显示操作列
  showAction: {
    type: Boolean,
    default: false
  },
  // 操作列标题
  actionLabel: {
    type: String,
    default: '操作'
  },
  // 操作列宽度
  actionWidth: {
    type: Number,
    default: 200
  },
  // 是否显示分页
  showPagination: {
    type: Boolean,
    default: true
  },
  // 分页配置
  pagination: {
    type: Object,
    default: () => ({
      currentPage: 1,
      pageSize: 10,
      pageSizes: [10, 20, 50, 100],
      total: 0,
      layout: 'total, sizes, prev, pager, next, jumper'
    })
  },
  // 是否显示搜索框
  showSearch: {
    type: Boolean,
    default: false
  },
  // 是否显示工具栏
  toolbar: {
    type: Boolean,
    default: false
  }
});

const emits = defineEmits([
  'selection-change',
  'sort-change',
  'size-change',
  'current-change',
  'search',
  'refresh'
]);

// 搜索文本
const searchText = ref('');
// 选中的行
const selectedRows = ref([]);
// 表格数据
const tableData = ref([]);

// 内部当前页码和每页条数
const innerCurrentPage = ref(props.pagination.currentPage);
const innerPageSize = ref(props.pagination.pageSize);

// 监听原始数据变化
watch(
  () => props.data,
  (newVal) => {
    tableData.value = newVal;
  },
  { immediate: true }
);

// 监听父组件pagination变化，同步更新内部值
watch(
  () => props.pagination,
  (newVal) => {
    innerCurrentPage.value = newVal.currentPage;
    innerPageSize.value = newVal.pageSize;
  },
  { deep: true, immediate: true }
);

// 处理选择变化
const handleSelectionChange = (val) => {
  emits('selection-change', val);
};

// 处理排序变化
const handleSortChange = (val) => {
  emits('sort-change', val);
};

// 处理内部页大小变化，触发事件给父组件
const handleInnerSizeChange = (val) => {
  emits('size-change', val);
};

// 处理内部页码变化，触发事件给父组件
const handleInnerCurrentChange = (val) => {
  emits('current-change', val);
};

// 处理搜索
const handleSearch = () => {
  emits('search', searchText.value);
};

// 暴露刷新方法
const refresh = () => {
  emits('refresh');
};

defineExpose({
  refresh,
  selectedRows
});
</script>

<style scoped lang="scss">
.custom-table-container {
  width: 100%;
  box-sizing: border-box;
}

.table-search {
  margin-bottom: 16px;
  display: flex;
  justify-content: flex-start;
}

.table-toolbar {
  margin-bottom: 16px;
  display: flex;
  justify-content: flex-start;
  gap: 8px;
}

.table-pagination {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
}
</style>
